package com.yc.utilslib.asynctask;


import android.os.AsyncTask;

import com.yc.utilslib.utils.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 作者：TanTun
 * 时间：2017/2/22
 * 邮箱：32965926@qq.com
 * 描述：WebApi异步请求
 */

public class WebApiRequest<TSuccess, TError> extends AsyncTask<String, Integer, TSuccess> {

    private String mErrorMessage = StringUtils.EMPTY;
    private TError mErr = null;

    private String method = "GET";
    private Map<String, String> head = new HashMap<>();

    private AsyncTaskSuccess<TSuccess> mSuccess;
    private AsyncTaskError<TError> mError;

    public interface AsyncTaskSuccess<TSuccess> {
        TSuccess parsing(String str);
        void success(TSuccess obj);
    }

    public interface AsyncTaskError<TError> {
        TError parsing(String str);
        void error(String msg);
        void error(TError obj);
    }

    public void setAsyncTaskSuccess(AsyncTaskSuccess<TSuccess> success) {
        mSuccess = success;
    }

    public void setAsyncTaskError(AsyncTaskError<TError> error) {
        mError = error;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public void setHead(String field, String value) {
        head.put(field, value);
    }

    private static String changeInputStream(InputStream inputStream, int len) {
        String str = "";
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        byte[] data = new byte[len];
        try {
            while ((len = inputStream.read(data)) != -1) {
                outputStream.write(data, 0, len);
            }
            str = new String(outputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    @Override
    protected TSuccess doInBackground(String... str) {

        TSuccess obj = null;

        try {
            URL url = new URL(str[0]);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setRequestMethod(method);

            if (head != null) {
                for (String key : head.keySet()
                     ) {
                    connection.addRequestProperty(key, head.get(key));
                }
            }

            if (method.equals("POST")) {
                connection.setDoOutput(true); // 发送POST请求必须设置允许输出
                // 获取URLConnection对象对应的输出流
                DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
                wr.writeBytes(str[1]);
                wr.flush();
                wr.close();
            }
            int code = connection.getResponseCode();
            if (code >= 200 && code < 300) {
                if (code != 204) {
                    String content = changeInputStream(connection.getInputStream(),
                            connection.getContentLength() > 0 ? connection.getContentLength() : 8129);
                    obj = mSuccess.parsing(content);
                }
            } else {
                String content = changeInputStream(connection.getErrorStream(),
                        connection.getContentLength() > 0 ? connection.getContentLength() : 8129);
                mErr = mError.parsing(content);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            mErrorMessage = e.getMessage();
        }

        return obj;
    }

    /**
     * 这里的String参数对应AsyncTask中的第三个参数（也就是接收doInBackground的返回值）
     * 在doInBackground方法执行结束之后在运行，并且运行在UI线程当中 可以对UI空间进行设置
     */
    @Override
    protected void onPostExecute(TSuccess result) {
        if (result != null) {
            mSuccess.success(result);
        } else if (mErr != null) {
            mError.error(mErr);
        } else if (!StringUtils.isNullOrEmpty(mErrorMessage)) {
            mError.error(mErrorMessage);
        }
    }
}
